using System;
using System.Collections.Generic;
using System.Text;
using CodePlex.Resourceful;

namespace CodePlex.SpaceBlock
{
    public class Path
    {
        public static readonly char SeparatorChar = '/';
        public static readonly string Separator = "/";
        public static readonly Path Root = Path.Parse(Separator);
        


        private readonly string[] _parts;

        private Path(string[] parts)
        {
            _parts = parts;
        }

        public string Name
        {
            get
            {
                return this.IsFolder ? _parts[_parts.Length - 2] : _parts[_parts.Length - 1];
            }
        }

        public bool IsFolder
        {
            get
            {
                return _parts[_parts.Length - 1].Length == 0;
            }
        }

        public int Level
        {
            get
            {
                return _parts.Length - (this.IsFolder ? 2 : 1);
            }
        }

        public string[] Parts
        {
            get
            {
                List<string> rt = new List<string>(_parts);

                if (this.IsFolder)
                {
                    rt.RemoveAt(rt.Count - 1);
                }
                rt.RemoveAt(0);

                return rt.ToArray();
            }
        }

        public Path Parent
        {
            get
            {
                if (this.Level == 0)
                {
                    return this;
                }

                string str = this.ToString();
                return Path.Parse(str.Substring(0,str.Length-this.Name.Length - (this.IsFolder?1:0)));
            }
        }

        public Path Combine(string value)
        {
            value = value==null?"":value;  
            return Path.Parse(this.ToString() + value);
        }

        public override string ToString()
        {
            return string.Join(Path.Separator, _parts);
        }
        public override int GetHashCode()
        {
            return this.ToString().GetHashCode();
        }

        public override bool Equals(object obj)
        {
            return obj is Path && this.ToString().Equals(obj.ToString());
        }

        public static Path Parse(string value)
        {
            if (value.Length == 0)
            {
                throw CodePlexException.Format("Path cannot be blank.");
            }

            string[] parts = value.Split(Path.SeparatorChar);

            // must start with the delim
            if (parts[0].Length > 0)
            {
                throw CodePlexException.Format("Path must begin with a delim: '{0}'.", value);
            }

            // no delims next to each other
            for (int i = 1; i < parts.Length - 1; i++)
            {
                if (parts[i].Length == 0)
                {
                    throw CodePlexException.Format("Invalid path: '{0}'.", value);
                }
            }

            return new Path(parts);
        }
    }
}
